 //============================================================================
// Copyright (C) 2010 Brett R. Jones
// All Rights Reserved
//
// You may redistribute and/or modify for non commercial and commercial uses
// provided this copyright notice remains in place and is not modified
//
// This code is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// brettjones1900@gmail.com
// http://www.p2panarchy.com
//============================================================================

#include "DtwGame.h"

#include <VxUtilLib/VxMathDef.h>

//------------------------------------------------------------------------------
//=== constructor ===//
DtwStatePlay::DtwStatePlay()
	: m_u32AppTimeLastUpdateMs(0)		// time of last update in millisec since app started
	, m_u32MsElapsedThisFrame(0)		// milliseconds elapsed this frame ( time in millisec since last update )
	, m_iComet1Seconds(0)
	, m_iComet2Seconds(0)
	, m_iAsteroidRedSeconds(0)
	, m_iAsteroidBlueSeconds(0)
	, m_iCheckIfEarthDestroyedSeconds(0)
	, m_u32LastSysTimeSec(0)

	, m_poEntEarth(0)
	// comet fire
	, m_poEntCometRed(0)

	// comet ice
	, m_poEntCometBlue(0)
	
	// asteroid red
	, m_poEntAsteroidRed(0)
	, m_iAsteroidRedFireInterval(0)
	// asteroid blue
	, m_poEntAsteroidBlue(0)
	, m_iAsteroidBlueFireInterval(0)

	//=== game state vars ===//
	, m_bRunning(0)

	//=== touch vars ===//
	, m_u32TouchStartMs(0)	// start time in ms of touch
	, m_f32TouchDnX(0.0f)	// touch start position X
	, m_f32TouchDnY(0.0f)	// touch start position Y
	, m_f32TouchUpX(0.0f) 		// x position of touch up event
	, m_f32TouchUpY(0.0f) 		// y position of touch up event
	, m_bIsLongPress(0)		// if true is a long press
	, m_f32ScaledTouchSlopSquared(100.0f) // touch distance slop based on screen size
	, m_bTouchHasNotMoved(0) // if true touch was not moved from start ( except within slop distance )
	, m_poTouchSceneNode(0)		// scene node touched during touch down event
	, m_iYAxisAvgIdx(0)
{
	memset( m_af32YAxisOrientationAvg, 0, Y_AXIS_ORIENTATION_MAX_SAMPLES * sizeof( float  ) );
}

//------------------------------------------------------------------------------
//=== destructor ===//
DtwStatePlay::~DtwStatePlay()
{
}

//------------------------------------------------------------------------------
//! startup
RCODE DtwStatePlay::GameStateStartup( VxIrrBase * poIrrBase )
{
	vx_assert( poIrrBase );
	log_msg( 0, "DtwStatePlay::GameStateStartup: start\n" );
	GameStateBase::GameStateStartup(  poIrrBase );
	//log_msg( 0, "10 Game Instance %d\n", m_poIrrBase->m_iGameInstance  );
	m_poGameMgr = (DtwGameMgr *)poIrrBase;
	m_poIrrBase->m_iGameInstance++;

	log_msg( 0, "DtwStatePlay::GameStateStartup: starting instance %d\n", m_poIrrBase->m_iGameInstance  );
	m_poEntEarth = 0;
	m_poEntCometRed = 0;
	m_poEntCometBlue = 0;
	m_poEntAsteroidRed = 0;

	m_iComet1Seconds = 0;
	m_iComet2Seconds = 0;
	m_iAsteroidRedSeconds = 0;
	m_iAsteroidBlueSeconds = 0;
	m_iCheckIfEarthDestroyedSeconds = 0;
	m_u32LastSysTimeSec = 0;

	m_f32ScaledTouchSlopSquared = ((float)m_poIrrBase->m_iScnSizeX/32) * ((float)m_poIrrBase->m_iScnSizeY/48);
	log_msg( 0, "Game startup screen w=%d, h=%d\n", m_poIrrBase->m_iScnSizeX, m_poIrrBase->m_iScnSizeY );
	m_poIrrBase->m_poCam = new DtwCamera( m_poIrrBase, 0, 0);
	m_poIrrBase->m_poCam->SetScreenSize( m_poIrrBase->m_iScnSizeX, m_poIrrBase->m_iScnSizeY );

	log_msg( 0, "Game startup: loading resources\n");
	LoadResources( false );
	log_msg( 0, "Game startup: creating progress bar\n");

	m_poEntAsteroidBlue->m_poSceneNode->setID(4); // so is not considered in searches for touch
	m_poEntAsteroidRed->m_poSceneNode->setID(8); // so is not considered in searches for touch

	m_poProgressBar = new irr::scene::VxProgressBarNode(	m_poSceneMgr->getRootSceneNode(),		
		m_poSceneMgr, 
		-1,
		2,		// x position on screen
		m_poIrrBase->m_iScnSizeY - 22,		// y position on screen
		m_poIrrBase->m_iScnSizeX - 4, // width
		20 ); // height

	//m_poProgressBar->setDebugDataVisible( true );
	//m_poEntAsteroidBlue->m_poSceneNode->setDebugDataVisible( true );
	//m_poEntAsteroidRed->m_poSceneNode->setDebugDataVisible( true );

	log_msg( 0, "rendering first scene\n");
	// run scene manager so that camera project gets set
	// so WorldToScreen and ScreenToWorld work
	log_msg( 0, "begin scene\n");
	m_poDriver->beginScene(true, true, irr::video::SColor(255,255,0,0));
	log_msg( 0, "scene draw all\n");
	m_poSceneMgr->drawAll();
	log_msg( 0, "gui draw all\n");
	m_poGui->drawAll();
	log_msg( 0, "end scene\n");
	m_poDriver->endScene();
	log_msg( 0, "calculating world limits\n");
	CalculateWorldLimits();
	log_msg( 0, "calculating geometry\n");
	DetermineGeometry();
	log_msg( 0, "Game Initialized\n");

	// show game version
	irr::core::stringw strTime = L"0000";
	m_poTextGameTime = m_poGui->addStaticText( strTime.c_str(),  irr::core::rect<irr::s32>(5, 5, 200, 50 ), false, false );
	m_poTextGameTime->setOverrideFont( m_poIrrBase->m_poDefaultFont );
	m_poTextFps = m_poGui->addStaticText( strTime.c_str(),  irr::core::rect<irr::s32>(5, 100, 200, 250 ), false, false );
	//m_poTextFps->setOverrideFont( m_poIrrBase->m_poDefaultFont );

	switch( m_poIrrBase->m_iGameLevel )
	{
	case 1:
		m_iAsteroidBlueFireInterval = 2;
		m_iAsteroidRedFireInterval = 5;
		m_f32AsteroidBlueVelocity = 65.0f;
		m_f32AsteroidRedVelocity = 70.0f;
		m_poIrrBase->m_iGameScore = 10000;
		break;
	case 2:
		m_iAsteroidBlueFireInterval = 10;
		m_iAsteroidRedFireInterval = 13;
		m_f32AsteroidBlueVelocity = 90.0f;
		m_f32AsteroidRedVelocity = 99.0f;
		m_poIrrBase->m_iGameScore = 10000;
		break;
	case 3:
		m_iAsteroidBlueFireInterval = 20;
		m_iAsteroidRedFireInterval = 23;
		m_f32AsteroidBlueVelocity = 120.0f;
		m_f32AsteroidRedVelocity = 129.0f;
		m_poIrrBase->m_iGameScore = 10000;
		break;
	}
	m_poIrrBase->m_iGameTime = 0;
	m_poIrrBase->m_iGameHits = 0;
	m_poIrrBase->m_iGameMisses = 0;
	m_poIrrBase->m_iGameBonusPoints = 0;
	m_poIrrBase->m_u32GameTimeMs = 0;

	m_bRunning = true;
	log_msg( 0, "DtwStatePlay::GameStateStartup: success\n" );

	return 0;
}

//------------------------------------------------------------------------------
//! shutdown
void DtwStatePlay::GameStateShutdown( void )
{
	log_msg( 0, "DtwStatePlay::GameStateShutdown: start\n" );
	m_bRunning = false;
	m_poIrrBase->ClearTimedMessages();
	// tell level manage to unload
	g_GameLevelMgrImp.GameLevelShutdown();

	m_poSceneMgr->clear();
	m_poGui->clear();
	m_poDriver->removeAllTextures();

	log_msg( 0, "DtwStatePlay::GameStateShutdown: success\n" );
}

//------------------------------------------------------------------------------
//! find scene node touched from cursor position ( NULL if no collision )
irr::scene::ISceneNode * DtwStatePlay::TouchedSceneNode(	irr::core::position2d<irr::s32> pos,// cursor position
															irr::s32 s32Range,					// check at four corners at this distance from cursor position
															irr::s32 s32ObjIdMask	)			// object id mask when checking for picked object
{
	irr::scene::ISceneNode * poNode = m_poCollideMgr->getSceneNodeFromScreenCoordinatesBB( pos, s32ObjIdMask );
	if( (0 == s32Range) || ( NULL != poNode ) )
	{
		return poNode;
	}
	if( NULL == poNode )
	{
		// not found so check upper left corner
		pos.X -= s32Range;
		pos.Y -= s32Range;
		if( (pos.X >= 0) && (pos.Y >= 0) )
		{
			poNode = m_poCollideMgr->getSceneNodeFromScreenCoordinatesBB( pos, s32ObjIdMask );
		}
	}
	if( NULL == poNode )
	{
		// not found so check upper right corner
		pos.X += s32Range * 2;
		if( (pos.X >= 0) && (pos.Y >= 0) )
		{
			poNode = m_poCollideMgr->getSceneNodeFromScreenCoordinatesBB( pos, s32ObjIdMask );
		}
	}
	if( NULL == poNode )
	{
		// not found so check lower right corner
		pos.Y += s32Range * 2;
		if( (pos.X >= 0) && (pos.Y >= 0) )
		{
			poNode = m_poCollideMgr->getSceneNodeFromScreenCoordinatesBB( pos, s32ObjIdMask );
		}
	}
	if( NULL == poNode )
	{
		// not found so check lower left corner
		pos.X -= s32Range * 2;
		if( (pos.X >= 0) && (pos.Y >= 0) )
		{
			poNode = m_poCollideMgr->getSceneNodeFromScreenCoordinatesBB( pos, s32ObjIdMask );
		}
	}
	return poNode;
}
//------------------------------------------------------------------------------
//! game object touched then released.. determine what to do
void DtwStatePlay::GameObjToss( void )
{
	//log_msg( 0, "GameObjToss: checking if is comet\n" );
	if( (false == m_poEntCometRed->IsMySceneNode( m_poTouchSceneNode )) &&
		(false == m_poEntCometBlue->IsMySceneNode( m_poTouchSceneNode )) )
	{
		// for now we only toss comets
		log_msg( 0, "GameObjToss: not a comet\n" );
		return;
	}

	// from 2d touch points determine where the start touch intersects the xz plane
	irr::core::vector3df v3fTouchStartPoint;
	irr::core::vector3df v3fTouchEndPoint;

	//log_msg( 0, "GameObjToss: GetXZPlaneIntersect\n" );
	if( false == m_poIrrBase->GetXZPlaneIntersect( (int) m_f32TouchDnX, (int) m_f32TouchDnY, v3fTouchStartPoint ) )
	{
		log_msg( 0, "DtwStatePlay::GameObjToss: no XZ intersect of start point\n" );
	}

	//log_msg( 0, "GameObjToss: GetXZPlaneIntersect\n" );
	if( false == m_poIrrBase->GetXZPlaneIntersect( (int) m_f32TouchUpX, (int) m_f32TouchUpY, v3fTouchEndPoint ) )
	{
		log_msg( 0, "DtwStatePlay::GameObjToss: no XZ intersect of start point\n" );
	}

	// calculate direction to fire the comet
	irr::core::vector3df v3fTossDirection = v3fTouchEndPoint - v3fTouchStartPoint;
	v3fTossDirection.normalize();

	if( m_poEntCometRed->IsMySceneNode( m_poTouchSceneNode ) ) 
	{
		log_msg( 0, "Tossing red comet \n");
		m_poEntCometRed->SetLinearVelocity( btVector3( 150.0f * v3fTossDirection.X, 150.0f * v3fTossDirection.Y, 150.0f * v3fTossDirection.Z ) );
		m_poEntCometRed->m_poRigidBody->activate(true);
		//m_poEntCometRed->ApplyForce( btVector3( 50.5f, 0.0f, 50.5f ) );
	}
	if( m_poEntCometBlue->IsMySceneNode( m_poTouchSceneNode ) )
	{
		log_msg( 0, "Tossing blue comet \n");
		m_poEntCometBlue->SetLinearVelocity( btVector3( 150.0f * v3fTossDirection.X, 150.0f * v3fTossDirection.Y, 150.0f * v3fTossDirection.Z ) );
		m_poEntCometBlue->m_poRigidBody->activate(true);
	}

	//log_msg( 0, "GameObjToss: done\n" );
}

//------------------------------------------------------------------------------
//! update current game state.. time is millisec since app started
RCODE DtwStatePlay::GameStateUpdate( U32 u32AppTimeMs )
{
	// calculate elapsed time
	m_u32MsElapsedThisFrame = u32AppTimeMs - m_u32AppTimeLastUpdateMs;// milliseconds elapsed this frame
	if( m_u32MsElapsedThisFrame > 200 )
	{
		// limit elapsed time to 200 ms in case system hicuped
		m_u32MsElapsedThisFrame = 200;
	}
	m_u32AppTimeLastUpdateMs = u32AppTimeMs;

	m_poIrrBase->m_poTimer->tick();
	m_poDriver->beginScene(true, true, irr::video::SColor(255,255,0,0));

	// do any walk and pre physics stuff here
	g_EntMgrImp.BeginFrame(); // let all enities have chance to prepare

	// run physics
	m_poIrrBase->m_poPhysBase->PhysStep( m_u32MsElapsedThisFrame );

	// update camera position etc before render
	g_EntMgrImp.Update( m_u32MsElapsedThisFrame ); // let all enities handle update

	// render the scene
	m_poSceneMgr->drawAll();
	m_poGui->drawAll();

	g_EntMgrImp.EndFrame(); // let all enities handle end of frame

	// done rendering scene
	m_poDriver->endScene();


	if( false == m_oWorldBBox.isPointInside( m_poEntCometRed->GetIrrPosition() ) )
	{
		m_poEntCometRed->ResetToStartingPosition();
	}

	if( false == m_oWorldBBox.isPointInside( m_poEntCometBlue->GetIrrPosition() ) )
	{
		m_poEntCometBlue->ResetToStartingPosition();
	}
	
	m_poIrrBase->m_u32GameTimeMs += m_u32MsElapsedThisFrame; //; track game time
	if( g_u32SysTimeSec != m_u32LastSysTimeSec )
	{
		m_u32LastSysTimeSec = g_u32SysTimeSec;
		m_poIrrBase->GamePlayOncePerSecond();

		// update frames per second 
		int iFps = m_poDriver->getFPS();
		irr::core::stringw strText;
		strText.Format( "FPS: %d", iFps );
		m_poTextFps->setText( strText.c_str() );

		// update game time text
		strText.Format( "Time: %d", m_poIrrBase->m_iGameTime );
		m_poTextGameTime->setText( strText.c_str() );


		if( m_poEntCometRed->GetIrrPosition() != m_poEntCometRed->m_v3fStartPosition )
		{
			m_iComet1Seconds++;
			if( m_iComet1Seconds > 10 )
			{
				// comet has wandered somewhere without enough momentum to reach edge of world
				//log_msg( 0, "Reseting to start comet 1\n" );
				m_poEntCometRed->ResetToStartingPosition();
			}
		}
		else
		{
			m_iComet1Seconds = 0;
		}


		if( m_poEntCometBlue->GetIrrPosition() != m_poEntCometBlue->m_v3fStartPosition )
		{
			m_iComet2Seconds++;
			if( m_iComet2Seconds > 10 )
			{
				// comet has wandered somewhere without enough momentum to reach edge of world
				//log_msg( 0, "Reseting to start comet 2\n" );
				m_poEntCometBlue->ResetToStartingPosition();
			}
		}
		else
		{
			m_iComet2Seconds = 0;
		}

		if( m_poEntAsteroidRed->GetIrrPosition() != m_poEntAsteroidRed->m_v3fStartPosition )
		{
			m_iAsteroidRedSeconds++;
			if( m_iAsteroidRedSeconds > 15 )
			{
				// asteroid has wandered somewhere without enough momentum to reach edge of world
				//log_msg( 0, "Reseting to start asteroid red\n" );
				m_iAsteroidRedSeconds = 0;
				m_poEntAsteroidRed->ResetToStartingPosition();
			}
		}
		else
		{
			m_iAsteroidRedSeconds = 0;
			m_poEntAsteroidRed->m_iTimeInStartPos++;
			if( m_poEntAsteroidRed->m_iTimeInStartPos > m_iAsteroidRedFireInterval )
			{
				FireRedAsteroid();
			}
		}

		if( m_poEntAsteroidBlue->GetIrrPosition() != m_poEntAsteroidBlue->m_v3fStartPosition )
		{
			m_iAsteroidBlueSeconds++;
			if( m_iAsteroidBlueSeconds > 15 )
			{
				// asteroid has wandered somewhere without enough momentum to reach edge of world
				//log_msg( 0, "Reseting to start asteroid blue\n" );
				m_iAsteroidBlueSeconds = 0;
				m_poEntAsteroidBlue->ResetToStartingPosition();
				FireBlueAsteroid();
			}
		}
		else
		{
			m_iAsteroidBlueSeconds = 0;
			m_poEntAsteroidBlue->m_iTimeInStartPos++;
			if( m_poEntAsteroidBlue->m_iTimeInStartPos > m_iAsteroidBlueFireInterval )
			{
				FireBlueAsteroid();
			}
		}


		if( m_poIrrBase->m_bNeedProgressUpdate )
		{
			int iPercentDestroyed = (int)m_poEntEarth->GetPercentOfEarthDestroyed();
			m_poIrrBase->m_bNeedProgressUpdate = false;
			UpdateProgress( iPercentDestroyed );
		}

		g_EntMgrImp.OncePerSecond();
		if( m_poIrrBase->m_iGameInstance > 1 )
		{
			log_msg( 0, "GameStateUpdate EntMgr Once Per Second done\n");
		}
	}

	return 0;
}

//----------------------------------------------------------------------------
//! called when application is about to sleep
RCODE DtwStatePlay::GameStateAppSleep( void )
{
	return 0;
}
//----------------------------------------------------------------------------
//! called when application is resuming from sleep.. app must reload textures etc
RCODE DtwStatePlay::GameStateAppResume( U32 u32FrameTimeMs )
{
	// so physics doesnt hicup
	m_u32AppTimeLastUpdateMs = u32FrameTimeMs;

	// reload resources
	return LoadResources( true );
}

//----------------------------------------------------------------------------
//! interpolate before draw
void DtwStatePlay::InterpolatePositions( F32 f32TimeMs )
{
}
//----------------------------------------------------------------------------
//! draw scene
void DtwStatePlay::Draw( void )
{
}

//----------------------------------------------------------------------------
//! earth is destroyed.. play animations etc
void DtwStatePlay::DoDestroyEarth( void )
{
}

//----------------------------------------------------------------------------
//! load or reload resources
//! bReloadFromResume = true if reloading after application resume
RCODE DtwStatePlay::LoadResources( BOOL bReloadFromResume  )
{
	RCODE rc = 0;
	if( bReloadFromResume )
	{
		// TODO
		// unload previous resources
	}
	// load level
	log_msg( 0, "DtwStatePlay::LoadResources: loading xml\n" );
	switch( m_poIrrBase->m_iGameLevel )
	{
	case 3:
		rc = g_GameLevelMgrImp.GameLevelStartup( m_poIrrBase, "level_hard.xml", bReloadFromResume );
		break;
	case 2:
		rc = g_GameLevelMgrImp.GameLevelStartup( m_poIrrBase, "level_medium.xml", bReloadFromResume );
		break;
	case 1:
	default:
		rc = g_GameLevelMgrImp.GameLevelStartup( m_poIrrBase, "level_easy.xml", bReloadFromResume );
		break;
	}
	log_msg( 0, "DtwStatePlay::LoadResources: done loading xml\n" );

	if( 0 == rc )
	{
		// spawn all entities in level
		//	g_GameLevelMgrImp.SpawnAllEntities();

		EntBase * poEnt;
		for( U32 i = 0; i < g_GameLevelMgrImp.m_apoEntSpawnData.size(); i++) 
		{
			log_msg( 0, "DtwStatePlay::LoadResources: spawn index %d\n", i );
			EntSpawnData * poEntSpawnData = g_GameLevelMgrImp.m_apoEntSpawnData[i];
			poEnt = g_GameLevelMgrImp.CreateEntitiy( *poEntSpawnData );
			if( poEnt->GetProperName() == "Comet 1" )
			{
				m_poEntCometRed = (EntCometFire *)poEnt;
			}
			else if( poEnt->GetProperName() == "Comet 2" )
			{
				m_poEntCometBlue = (EntCometIce *)poEnt;
			}
			else if( poEnt->GetProperName() == "Earth" )
			{
				m_poEntEarth = (EntEarth *)poEnt;
			}
			else if( poEnt->GetProperName() == "Asteroid Red" )
			{
				m_poEntAsteroidRed = (EntAsteroidRed *)poEnt;
			}
			else if( poEnt->GetProperName() == "Asteroid Blue" )
			{
				m_poEntAsteroidBlue = (EntAsteroidBlue *)poEnt;
			}
			else 
			{
				log_msg( 0, "DtwStatePlay::LoadResources: Unknown Ent\n" );
			}
		}
	}

	return rc;
}
//----------------------------------------------------------------------------
//! update percent of earth destroyed
void DtwStatePlay::UpdateProgress( int iPercentDestroyed )
{
	int iPercentProgress = (91 - (iPercentDestroyed * 2));
	m_poProgressBar->setProgress( iPercentProgress );

	//if( iPercentProgress <= 90 )
	if( iPercentProgress <= 2 )
	{
		// switch to cutscene of earth exploding
		GameLevelCompleted();
	}
}
//----------------------------------------------------------------------------
//! do level completed action
void DtwStatePlay::GameLevelCompleted( void )
{
	switch( m_poGameMgr->m_iGameLevel )
	{
	case 1:
		m_poGameMgr->m_iGameScore -= m_poGameMgr->m_iGameTime * 20;
		break;
	case 2:
		m_poGameMgr->m_iGameScore -= m_poGameMgr->m_iGameTime * 10;
		break;
	case 3:
		m_poGameMgr->m_iGameScore -= m_poGameMgr->m_iGameTime * 5;
		break;
	}

	m_poGameMgr->m_iGameScore = m_poGameMgr->m_iGameScore - m_poGameMgr->m_iGameTime;
	m_poGameMgr->m_iGameScore += m_poGameMgr->m_iGameHits * 100;
	m_poGameMgr->m_iGameScore -= m_poGameMgr->m_iGameMisses * 50;
	if( m_poGameMgr->m_iGameScore < 0 )
	{
		m_poGameMgr->m_iGameScore = 10;
	}
	m_poGameMgr->m_iGameScore += m_poGameMgr->m_iGameBonusPoints;

	// switch to exploding earth cut scene
	m_poGameMgr->m_poNewState = new DtwStateCutScene();
}

//----------------------------------------------------------------------------
void DtwStatePlay::FireRedAsteroid( void )
{
	// remove old animator
	if( NULL != m_poEntAsteroidRed->m_poRotAnimator )
	{
		m_poEntAsteroidRed->m_poSceneNode->removeAnimator( m_poEntAsteroidRed->m_poRotAnimator );
	}
	// add new rotation animator
	m_poEntAsteroidRed->m_poRotAnimator = m_poSceneMgr->createRotationAnimator( irr::core::vector3df(Rand0To1(), 0.0f, Rand0To1()) );
	m_poEntAsteroidRed->m_poSceneNode->addAnimator( m_poEntAsteroidRed->m_poRotAnimator );
	// fire asteroid
	irr::core::vector3df v3fPos = m_poEntAsteroidRed->m_poSceneNode->getPosition();
	m_poEntAsteroidRed->SetLinearVelocity( btVector3( 0.0f, 0.0f,  m_f32AsteroidRedVelocity ) );
	m_poEntAsteroidRed->m_poRigidBody->activate(true);
}

//----------------------------------------------------------------------------
void DtwStatePlay::FireBlueAsteroid( void )
{
	// remove old animator
	if( NULL != m_poEntAsteroidBlue->m_poRotAnimator )
	{
		m_poEntAsteroidBlue->m_poSceneNode->removeAnimator( m_poEntAsteroidBlue->m_poRotAnimator );
	}
	// add new rotation animator
	m_poEntAsteroidBlue->m_poRotAnimator = m_poSceneMgr->createRotationAnimator( irr::core::vector3df(Rand0To1(), 0.0f, Rand0To1() ) );
	m_poEntAsteroidBlue->m_poSceneNode->addAnimator( m_poEntAsteroidBlue->m_poRotAnimator );
	// fire asteroid
	irr::core::vector3df v3fPos = m_poEntAsteroidBlue->m_poSceneNode->getPosition();
	m_poEntAsteroidBlue->SetLinearVelocity( btVector3( 0.0f, 0.0f,  m_f32AsteroidBlueVelocity ) );
	m_poEntAsteroidBlue->m_poRigidBody->activate(true);
}


